<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>数据统计</title>
		<link rel="stylesheet" href="../component/pear/css/pear.css" />
		<style>
			.layui-form-radio>.lay-skin-tag,
			.layui-form-checkbox>.lay-skin-tag {font-size: 14px; border-radius: 2px; padding: 3px 6px;}
			.layui-form-checked>.lay-skin-tag,
			.layui-form-radioed>.lay-skin-tag {color: #fff !important;}
			.layui-form-radio:hover *, .layui-form-radioed, .layui-form-radioed>i {color: #ffffff !important;}
		</style>
	</head>
	<body class="pear-container">
		<div class="layui-row layui-col-space10">
			<div class="layui-col-md2">
				<div class="layui-card">
					<div class="layui-card-body">
						<div class="layui-row layui-padding-1">
							<div class="layui-col-md12">
								<div>今日请求</div>
							</div>
						</div>
						<div class="layui-row layui-padding-1">
							<div class="layui-col-md12 layui-font-24">
								<div id="request_times">0</div>
							</div>
						</div>
					</div>
				</div>
			</div>
			<div class="layui-col-md8">
				<div class="layui-card">
					<div class="layui-card-body">
						<div class="layui-row">
							<div class="layui-col-md12 layui-padding-1">
								<div>今日拦截</div>
							</div>
						</div>
						<div class="layui-row">
							<div class="layui-col-md3 layui-padding-1 layui-font-24">
								<div id="block_times">0</div>
							</div>
							<div class="layui-col-md9 layui-padding-1 layui-font-14">
								<div class="layui-row">
									<div class="layui-col-md4">攻击阻断：<span id="block_times_attack">0</span></div>
									<div class="layui-col-md4">人机验证：<span id="block_times_captcha">0</span></div>
									<div class="layui-col-md4">CC拦截：<span id="block_times_cc">0</div></span>
								</div>
							</div>
						</div>
					</div>
				</div>
			</div>
			<div class="layui-col-md2">
				<div class="layui-card">
					<div class="layui-card-body">
						<div class="layui-row layui-padding-1">
							<div class="layui-col-md12">
								<div>今日人机验证通过</div>
							</div>
						</div>
						<div class="layui-row layui-padding-1">
							<div class="layui-col-md12 layui-font-24">
								<div id="captcha_pass_times">0</div>
							</div>
						</div>
					</div>
				</div>
			</div>
		</div>
		<div class="layui-row layui-col-space10">
			<div class="layui-col-md12">
				<div class="layui-card">
					<div class="layui-card-body">
						<div class="layui-row layui-col-space20">
							<div class="layui-col-md6">
								<div class="layui-row">
									<div class="layui-col-md6">
										<div class="layui-row layui-padding-1">
											<div class="layui-col-md12">
												<div>4xx错误数量</div>
											</div>
										</div>
										<div class="layui-row layui-padding-1">
											<div class="layui-col-md12 layui-font-24">
												<div id="http4xx">0</div>
											</div>
										</div>
									</div>
									<div class="layui-col-md6">
										<div class="layui-row layui-padding-1">
											<div class="layui-col-md12">
												<div>4xx错误率</div>
											</div>
										</div>
										<div class="layui-row layui-padding-1">
											<div class="layui-col-md12 layui-font-24">
												<div id="http4xxPercent">0%</div>
											</div>
										</div>
									</div>
								</div>
							</div>
							<div class="layui-col-md6">
								<div class="layui-row">
									<div class="layui-col-md6">
										<div class="layui-row layui-padding-1">
											<div class="layui-col-md12">
												<div>5xx错误数量</div>
											</div>
										</div>
										<div class="layui-row layui-padding-1">
											<div class="layui-col-md12 layui-font-24">
												<div id="http5xx">0</div>
											</div>
										</div>
									</div>
									<div class="layui-col-md6">
										<div class="layui-row layui-padding-1">
											<div class="layui-col-md12">
												<div>5xx错误率</div>
											</div>
										</div>
										<div class="layui-row layui-padding-1">
											<div class="layui-col-md12 layui-font-24">
												<div id="http5xxPercent">0%</div>
											</div>
										</div>
									</div>
								</div>
							</div>
						</div>
					</div>
				</div>
			</div>
		</div>
		<div class="layui-row layui-col-space10">
			<div class="layui-col-md6">
				<div class="layui-card">
					<div class="layui-card-body">
						<div id="traffic" style="min-height:400px;"></div>
					</div>
				</div>
			</div>
			<div class="layui-col-md6">
				<div class="layui-card">
					<div class="layui-card-body">
						<div id="attackType" style="min-height:400px;"></div>
					</div>
				</div>
			</div>
		</div>
		<div class="layui-row layui-col-space10">
			<div class="layui-col-md12">
				<div class="layui-card">
					<div class="layui-card-body">
						<div class="layui-row">
							<div class="layui-col-md8">
								<div id="china" style="min-height:400px;"></div>
							</div>
							<div class="layui-col-md4">
								<div class="layui-row layui-form">
									<div class="layui-col-md4">
										<input type="radio" name="regionType" value="1" lay-filter="radio_filter_region" lay-skin="none" checked>
										<div lay-radio class="lay-skin-tag theme-color">世界</div>
										<input type="radio" name="regionType" value="2" lay-filter="radio_filter_region" lay-skin="none">
										<div lay-radio class="lay-skin-tag theme-color">中国</div>
									</div>
									<div class="layui-col-md4" style="text-align: right;">
										<input type="radio" name="trafficType" value="1" lay-filter="radio_filter_traffic" lay-skin="none" checked>
										<div lay-radio class="lay-skin-tag theme-color">访问</div>
										<input type="radio" name="trafficType" value="2" lay-filter="radio_filter_traffic" lay-skin="none">
										<div lay-radio class="lay-skin-tag theme-color">拦截</div>
									</div>
									<div class="layui-col-md4"></div>
								</div>
								<div class="layui-row">
									<div class="layui-col-md12" id="rank"></div>
								</div>
							</div>
						</div>
					</div>
				</div>
			</div>
		</div>

		<script src="../component/layui/layui.js"></script>
		<script src="../component/pear/pear.js"></script>
		<script src="../js/attackType.js"></script>

		<script>
			layui.use(['form','util','jquery','popup','echarts','laytpl'], function() {
				var $ = layui.$;
				var form = layui.form;
				var layer = layui.layer;
				var util = layui.util;
				var popup = layui.popup;
				let echarts = layui.echarts;
				var laytpl = layui.laytpl;
				var element = layui.element;

				var worldData = [];
				var chinaData = [];
				var mapChart = echarts.init(document.getElementById('china'));

				function updateMapData() {
					var sourceData = [];
					var convertedData = [];
					var mapType = 'world';

					var regionType = $('input[name="regionType"]:checked').val();
					var trafficType = $('input[name="trafficType"]:checked').val();

					if (regionType == 1) {
						mapType = 'world';
						sourceData = worldData;
					} else if (regionType == 2) {
						mapType = 'china';
						sourceData = chinaData;
					}

					if (trafficType == 1) {
						sourceData = sourceData.filter(obj => obj.request_times > 0);
						convertedData = sourceData.map(function(item) {
							return {
								name: item.name_cn,
								value: item.request_times
							};
						});
					} else if (trafficType == 2) {
						sourceData = sourceData.filter(obj => obj.block_times > 0);
						convertedData = sourceData.map(function(item) {
							return {
								name: item.name_cn,
								value: item.block_times
							};
						});
					}

					convertedData = convertedData.sort((a, b) => b.value - a.value);

					const maxTimes = convertedData.reduce((max, obj) => {
						return Math.max(max, obj.value);
					}, 0);

					var str = '{{# layui.each(d, function(index, item){'
						str += 'if(index>6){return;}';
						str += 'var max = ' + maxTimes + ' == 0 ? 1 :' + maxTimes + ';';
						str += 'var percent = item.value*100/max;';
						str += '}}';

						str += '<div class="layui-row layui-padding-1">';
						str += '<div class="layui-col-md4">{{= item.name}}</div>';
						str += '<div class="layui-col-md4" style="text-align: right;">{{= item.value}}</div>';
						str += '</div>';
						str += '<div class="layui-row layui-padding-1">';
						str += '<div class="layui-col-md8"><div class="layui-progress" lay-filter="progress"><div class="layui-progress-bar" lay-percent="{{= percent}}%"></div></div></div>';
						str += '</div>';
						str += '{{# }); }}';
					laytpl(str).render(convertedData, function(htmlStr) {
						$('#rank').html(htmlStr);
					});

					mapChart.setOption({visualMap: {max: maxTimes < 100 ? 100 : maxTimes},series: {type: 'map', mapType: mapType, data: convertedData}});
					element.render('progress', 'progress');
				}

				$.get('/admin/data/world.json', function(data) {
					echarts.registerMap('world', data);

					var mapOption = {
						tooltip: {
							trigger: 'item',
							formatter: function (params) {
								var name = params.name;
								return name + ': ' + (params.value ? params.value : 0);
							}
						},
						visualMap: {
							min: 1,
							max: 100,
							left: 'left',
							top: 'bottom',
							calculable: true,
							color: '#fafafa',
							inRange: {
								color: [
									'#fee090',
									'#ffcc80',
									'#ffa500',
									'#ff7f50',
									'#f05040',
									'#d73027',
									'#a50026'
								]
							},
							outOfRange: {
								color: '#eeeeee'
							},
							text: ['', ''],
							orient: 'horizontal',
							calculable: true
						},
						title: {
							left: 'left',
							top: 10,
							text: '30天访问来源地区'
						},
						series: {
							name: '30天访问来源地区',
							type: 'map', // 图表类型为地图
							mapType: 'world', // 地图类型为上面注册的类型
							roam: false, // 是否开启鼠标缩放和平移漫游
							label: {
								show: false, // 是否显示省份标签
							},
							itemStyle: {
								normal: {
									areaColor: '#eeeeee', // 非选中时默认区域颜色，这里可以根据需要设置
									borderColor: '#2f363c' // 区域边框颜色
								}
							},
							nameMap: {"Afghanistan":"阿富汗","Singapore":"新加坡","Angola":"安哥拉","Albania":"阿尔巴尼亚","United Arab Emirates":"阿联酋","Argentina":"阿根廷","Armenia":"亚美尼亚","French Southern and Antarctic Lands":"法属南半球和南极领地","Australia":"澳大利亚","Austria":"奥地利","Azerbaijan":"阿塞拜疆","Burundi":"布隆迪","Belgium":"比利时","Benin":"贝宁","Burkina Faso":"布基纳法索","Bangladesh":"孟加拉国","Bulgaria":"保加利亚","The Bahamas":"巴哈马","Bosnia and Herzegovina":"波斯尼亚和黑塞哥维那","Belarus":"白俄罗斯","Belize":"伯利兹","Bermuda":"百慕大","Bolivia":"玻利维亚","Brazil":"巴西","Brunei":"文莱","Bhutan":"不丹","Botswana":"博茨瓦纳","Central African Republic":"中非共和国","Canada":"加拿大","Switzerland":"瑞士","Chile":"智利","China":"中国","Côte d'Ivoire":"科特迪瓦","Ivory Coast":"象牙海岸","Cameroon":"喀麦隆","Dem. Rep. Congo":"刚果民主共和国","Republic of the Congo":"刚果共和国","Colombia":"哥伦比亚","Costa Rica":"哥斯达黎加","Cuba":"古巴","Northern Cyprus":"北塞浦路斯","Cyprus":"塞浦路斯","Czech Republic":"捷克共和国","Germany":"德国","Djibouti":"吉布提","Denmark":"丹麦","Dominican Republic":"多明尼加共和国","Algeria":"阿尔及利亚","Ecuador":"厄瓜多尔","Egypt":"埃及","Eritrea":"厄立特里亚","Spain":"西班牙","Estonia":"爱沙尼亚","Ethiopia":"埃塞俄比亚","Finland":"芬兰","Fiji":"斐","Falkland Islands":"福克兰群岛","France":"法国","Gabon":"加蓬","United Kingdom":"英国","Georgia":"格鲁吉亚","Ghana":"加纳","Guinea":"几内亚","Gambia":"冈比亚","Guinea Bissau":"几内亚比绍","Greece":"希腊","Greenland":"格陵兰","Guatemala":"危地马拉","French Guiana":"法属圭亚那","Guyana":"圭亚那","Honduras":"洪都拉斯","Croatia":"克罗地亚","Haiti":"海地","Hungary":"匈牙利","Indonesia":"印度尼西亚","India":"印度","Ireland":"爱尔兰","Iran":"伊朗","Iraq":"伊拉克","Iceland":"冰岛","Israel":"以色列","Italy":"意大利","Jamaica":"牙买加","Jordan":"约旦","Japan":"日本","Kazakhstan":"哈萨克斯坦","Kenya":"肯尼亚","Kyrgyzstan":"吉尔吉斯斯坦","Cambodia":"柬埔寨","Kosovo":"科索沃","Kuwait":"科威特","Laos":"老挝","Lebanon":"黎巴嫩","Liberia":"利比里亚","Libya":"利比亚","Sri Lanka":"斯里兰卡","Lesotho":"莱索托","Lithuania":"立陶宛","Luxembourg":"卢森堡","Latvia":"拉脱维亚","Morocco":"摩洛哥","Moldova":"摩尔多瓦","Madagascar":"马达加斯加","Mexico":"墨西哥","Macedonia":"马其顿","Mali":"马里","Myanmar":"缅甸","Montenegro":"黑山","Mongolia":"蒙古","Mozambique":"莫桑比克","Mauritania":"毛里塔尼亚","Malawi":"马拉维","Malaysia":"马来西亚","Namibia":"纳米比亚","New Caledonia":"新喀里多尼亚","Niger":"尼日尔","Nigeria":"尼日利亚","Nicaragua":"尼加拉瓜","Netherlands":"荷兰","Norway":"挪威","Nepal":"尼泊尔","New Zealand":"新西兰","Oman":"阿曼","Pakistan":"巴基斯坦","Panama":"巴拿马","Peru":"秘鲁","Philippines":"菲律宾","Papua New Guinea":"巴布亚新几内亚","Poland":"波兰","Puerto Rico":"波多黎各","North Korea":"北朝鲜","Portugal":"葡萄牙","Paraguay":"巴拉圭","Qatar":"卡塔尔","Romania":"罗马尼亚","Russia":"俄罗斯","Rwanda":"卢旺达","Western Sahara":"西撒哈拉","Saudi Arabia":"沙特阿拉伯","Sudan":"苏丹","South Sudan":"南苏丹","Senegal":"塞内加尔","Solomon Islands":"所罗门群岛","Sierra Leone":"塞拉利昂","El Salvador":"萨尔瓦多","Somaliland":"索马里兰","Somalia":"索马里","Republic of Serbia":"塞尔维亚","Suriname":"苏里南","Slovakia":"斯洛伐克","Slovenia":"斯洛文尼亚","Sweden":"瑞典","Swaziland":"斯威士兰","Syria":"叙利亚","Chad":"乍得","Togo":"多哥","Thailand":"泰国","Tajikistan":"塔吉克斯坦","Turkmenistan":"土库曼斯坦","East Timor":"东帝汶","Trinidad and Tobago":"特里尼达和多巴哥","Tunisia":"突尼斯","Turkey":"土耳其","United Republic of Tanzania":"坦桑尼亚","Uganda":"乌干达","Ukraine":"乌克兰","Uruguay":"乌拉圭","United States":"美国","Uzbekistan":"乌兹别克斯坦","Venezuela":"委内瑞拉","Vietnam":"越南","Vanuatu":"瓦努阿图","West Bank":"西岸","Yemen":"也门","South Africa":"南非","Zambia":"赞比亚","Korea":"韩国","Tanzania":"坦桑尼亚","Zimbabwe":"津巴布韦","Congo":"刚果","Central African Rep.":"中非","Serbia":"塞尔维亚","Bosnia and Herz.":"波黑","Czech Rep.":"捷克","W. Sahara":"西撒哈拉","Lao PDR":"老挝","Dem. Rep. Korea":"朝鲜","Falkland Is.":"福克兰群岛","Timor-Leste":"东帝汶","Solomon Is.":"所罗门群岛","Palestine":"巴勒斯坦","N. Cyprus":"北塞浦路斯","Aland":"奥兰群岛","Fr. S. Antarctic Lands":"法属南半球和南极陆地","Mauritius":"毛里求斯","Comoros":"科摩罗","Eq. Guinea":"赤道几内亚","Guinea-Bissau":"几内亚比绍","Dominican Rep.":"多米尼加","Saint Lucia":"圣卢西亚","Dominica":"多米尼克","Antigua and Barb.":"安提瓜和巴布达","U.S. Virgin Is.":"美国原始岛屿","Montserrat":"蒙塞拉特","Grenada":"格林纳达","Barbados":"巴巴多斯","Samoa":"萨摩亚","Bahamas":"巴哈马","Cayman Is.":"开曼群岛","Faeroe Is.":"法罗群岛","IsIe of Man":"马恩岛","Malta":"马耳他共和国","Jersey":"泽西","Cape Verde":"佛得角共和国","Turks and Caicos Is.":"特克斯和凯科斯群岛","St. Vin. and Gren.":"圣文森特和格林纳丁斯"},
							data: []
						}
					};

					mapChart.setOption(mapOption);
				}, "json");

				$.get('/admin/data/china.json', function(data) {
					echarts.registerMap('china', data);
				}, "json");

				var trafficChart = echarts.init(document.getElementById('traffic'));
				trafficOption = {
					legend: {
						icon: 'rect',
						type: 'scroll',
						orient: 'vertical',
						right: 10,
						top: 40,
						bottom: 20,
					},
					tooltip: {
						trigger: 'axis',
						position: function (pt) {
							return [pt[0], '10%'];
						}
					},
					dataset: {
						source: []
					},
					title: {
						left: 'left',
						top: 10,
						text: '流量统计'
					},
					toolbox: {
						feature: {
							saveAsImage: {}
						}
					},
					xAxis: {
						name: '时间',
						type: 'category',
						axisLabel: {
							interval: 0,
							rotate: 50,
							margin: 10,
							formatter: function (value, index) {
								return value.substring(11, 13) + '点';
							}
						}
					},
					yAxis: {
						name: '',
					},
					series: [
						{
							name: '请求量',
							type: 'line',
							smooth: true,
							areaStyle: { opacity: 0.1 }
						},
						{
							name: '攻击请求量',
							type: 'line',
							smooth: true,
							areaStyle: { opacity: 0.1 },
							itemStyle: { color: '#FF5722' }
						},
						{
							name: '拦截请求量',
							type: 'line',
							smooth: true,
							areaStyle: { opacity: 0.1 },
							itemStyle: { color: '#FFB800' }
						}
					]
				};

				trafficChart.setOption(trafficOption);

				var attackTypeChart = echarts.init(document.getElementById('attackType'));
				attactTypeOption = {
					legend: {
						icon: 'rect',
						type: 'scroll',
						orient: 'vertical',
						right: 10,
						top: 40,
						bottom: 20,
						formatter: function (name) {
							return getAttackTypeText(name.substring(23, name.length));
						}
					},
					tooltip: {
						trigger: 'item',
						formatter: function (params) {
							var name = params.name;
							name = getAttackTypeText(name.substring(23, name.length));
							return name + ': ' + params.value + ' ' + params.percent + '%'
						}
					},
					title: {
						left: 'left',
						top: 10,
						text: '攻击类型统计',
					},
					toolbox: {
						feature: {
							saveAsImage: {}
						}
					},
					series: [
						{
							name: '请求量',
							type: 'pie',
							radius: '50%',
							emphasis: {
								itemStyle: {
									shadowBlur: 10,
									shadowOffsetX: 0,
									shadowColor: 'rgba(0, 0, 0, 0.5)'
								}
							},
							label: {
								formatter: function (params) {
									var name = params.name;
									name = getAttackTypeText(name.substring(23, name.length));
									return name + ': ' + params.percent + '%'
								}
							},
							data: []
						}
					]
				};

				attackTypeChart.setOption(attactTypeOption);

				$.get('/dashboard', function (res) {
					if (res && res.code == 200) {
						var data = res.data;
						var wafStatus = data.wafStatus;
						var sourceRegion = data.sourceRegion;

						if (wafStatus) {
							var http4xx = wafStatus.http4xx ? wafStatus.http4xx : 0;
							var http5xx = wafStatus.http5xx ? wafStatus.http5xx : 0;
							var request_times = wafStatus.request_times ? wafStatus.request_times : 0;
							var attack_times = wafStatus.attack_times ? wafStatus.attack_times : 0;
							var block_times = wafStatus.block_times ? wafStatus.block_times : 0;
							var block_times_attack = wafStatus.block_times_attack ? wafStatus.block_times_attack : 0;
							var block_times_captcha = wafStatus.block_times_captcha ? wafStatus.block_times_captcha : 0;
							var block_times_cc = wafStatus.block_times_cc ? wafStatus.block_times_cc : 0;
							var captcha_pass_times = wafStatus.captcha_pass_times ? wafStatus.captcha_pass_times : 0;

							var http4xxPercent = request_times > 0 ? http4xx / request_times : 0;
							var http5xxPercent = request_times > 0 ? http5xx / request_times : 0;

							$('#request_times').text(request_times);
							$('#block_times').text(block_times);
							$('#block_times_attack').text(block_times_attack);
							$('#block_times_captcha').text(block_times_captcha);
							$('#block_times_cc').text(block_times_cc);
							$('#captcha_pass_times').text(captcha_pass_times);
							$('#http4xx').text(http4xx);
							$('#http5xx').text(http5xx);
							$('#http4xxPercent').text((http4xxPercent.toFixed(2) > 0 ? http4xxPercent.toFixed(2) : 0) + '%');
							$('#http5xxPercent').text((http5xxPercent.toFixed(2) > 0 ? http5xxPercent.toFixed(2) : 0) + '%');
						}

						if (sourceRegion) {
							worldData = sourceRegion.world;
							chinaData = sourceRegion.china;
							if (Array.isArray(worldData) == false) {
								worldData = [];
							}
							if (Array.isArray(chinaData) == false) {
								chinaData = [];
							}
						}

						updateMapData();

						trafficChart.setOption({
							dataset: {
								source: JSON.parse(data.trafficData)
							}
						});

						attackTypeChart.setOption({
							series: [
								{
									data: JSON.parse(data.attackTypeData)
								}
							]
						});
						return true;
					} else {
						popup.failure(res.msg);
						return false;
					}
				}, "json");

				form.on('radio', function(data){
					updateMapData();
				});

				window.onresize = function() {
					trafficChart.resize();
					attackTypeChart.resize();
					mapChart.resize();
				}
			});
		</script>
	</body>
</html>
